﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using ApplicationLibrary;
using ApplicationLibrary.DBManager;
using ApplicationLibrary.ExtendedControls;
using ApplicationLibrary.SqlConnector;
using Plumber.Accounting.Forms;
using Plumber.Accounting.ModuleData;
using Plumber.Accounting.Reports.DataSet;
using Plumber.Masters.ModuleData;
using ApplicationLibrary.CounterManager;
using Plumber.Accounting.Library;

namespace Plumber.Accounting.Reports
{
    public partial class TaxSummary : ApplicationLibrary.DBManager.ReportForm
    {
        private string Title = string.Empty;
        private EnumsManager<PeriodType> eMonthName = null;
        private DSTaxRegister dsTaxRegister = null;
        private DRMasterType drMasterType;
        private DRTaxCode drTaxCode = null;
        private DRLiquidationType drLiquidationTax = null;
        private EnumsManager<TaxRegisterType> eTaxRegister = null;
        private Dictionary<string, totals> taxTotals = new Dictionary<string, totals>();
        private int startPage = 0;
        private double totalAmount = 0;

        CounterManager counterManager = null;

        public TaxSummary()
            : base(Properties.Resources.FN_MonthlySummary)
        {
            InitializeComponent();
        }

        protected override void OnBatchExecute(string reportName)
        {
            //Title = string.Format("{0}_{1}_{2}", Properties.Resources.FN_MonthlySummary, cbbMonth.Text, cbbYear.Text);
            if (!LoadData())
            {
                MessageBox.Show(Properties.Resources.Msg_NoDataPeriod, Properties.Resources.Warning, MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            switch(eTaxRegister.GetValue())
            {
                case TaxRegisterType.E_TaxSale:
                    counterManager = new CounterManager(Counters.SaleTaxRegister.Int(), int.Parse(cbbYear.Text), Properties.Resources.CN_SaleTaxRegister);
                    startPage = counterManager.GetNewIntValue();
                    break;
                case TaxRegisterType.E_TaxPurchase:
                    counterManager = new CounterManager(Counters.PurchaseTaxRegister.Int(), int.Parse(cbbYear.Text), Properties.Resources.CN_PurchaseTaxRegister);
                    startPage = counterManager.GetNewIntValue();
                    break;
            }

            SetParameterValue("Title", string.Format(Properties.Resources.Msg_TaxSummary,
                cbbRegister.Text, cbbMonth.Text, cbbYear.Text));
            SetParameterValue("curYear", cbbYear.Text);
            SetParameterValue("StartPage", startPage -1);
            ShowReport(new RPTTaxRegister(), dsTaxRegister);

            LiquidationTaxUpdater.UpdateImport(eMonthName.GetValue().Int(), int.Parse(cbbYear.Text), eTaxRegister.GetValue(), TaxRegisterStatus.E_Provisional, totalAmount);
        }

        protected override void OnDisableControlsForRun()
        {
        }

        protected override void OnAttachData()
        {
            eTaxRegister = new EnumsManager<TaxRegisterType>(cbbRegister);
            eMonthName = new EnumsManager<PeriodType>(cbbMonth);
            eMonthName.DisplayItem += new EnumsManager<PeriodType>.DisplayEventHandler(eMonthName_DisplayItem);
            cbbMonth.SelectedValue = GlobalInfo.CurrentDate.Month;
            cbbYear.Text = GlobalInfo.CurrentDate.Year.ToString();

            dsTaxRegister = new DataSet.DSTaxRegister();
            drMasterType = new DRMasterType(DRMasterType.Module.All);
            drTaxCode = new DRTaxCode(false);
            drLiquidationTax = new DRLiquidationType();

            for (int t = 2011; t <= GlobalInfo.CurrentDate.Year; t++)
                cbbYear.Items.Add(t);

            cbbYear.Text = GlobalInfo.CurrentDate.Year.ToString();
            if (drLiquidationTax.GetValue<LiquidationType>(PL_LiquidationType.Type) == LiquidationType.E_Montly)
                cbbMonth.Text = eMonthName.GetText(GlobalInfo.CurrentDate.Month - 1);
            else
                cbbMonth.Text = eMonthName.GetText((GlobalInfo.CurrentDate.Month-1) / 4);

            AddClickableColumn(PL_JournalEntry.JournalNo);
        }

        private bool eMonthName_DisplayItem(PeriodType e)
        {
            if (drLiquidationTax.GetValue<LiquidationType>(PL_LiquidationType.Type) == LiquidationType.E_Montly)
                return e <= PeriodType.E_December;
            else
                return e >= PeriodType.E_1_Quarterly;
        }

        protected override void OnDoubleClickColumn(string column, string value, CrystalDecisions.Windows.Forms.ObjectInfo[] objectInfo)
        {
            if (column == PL_JournalEntry.JournalNo.Name)
            {
                JournalEntriesSalePurchase frm = (JournalEntriesSalePurchase)GlobalInfo.OpenForm("Plumber.Plumber.Accounting.Forms.JournalEntriesSalePurchase", false);
                frm.FindRecord(new RadarJournalEntryParam(value));
            }
        }

        protected override void OnBindData()
        {
        }

        protected override void OnPrinted()
        {
            TaxRegisterStatus status = rdbFinal.Checked
                ? TaxRegisterStatus.E_Final
                : TaxRegisterStatus.E_Provisional;
            LiquidationTaxUpdater.UpdateImport(eMonthName.GetValue().Int(), int.Parse(cbbYear.Text), eTaxRegister.GetValue(), status, totalAmount);
            if (rdbFinal.Checked)
                counterManager.SetValue(startPage + GetPages() - 1);
        }

        private bool LoadData()
        {
            dsTaxRegister.Clear();
            taxTotals.Clear();

            QueryBuilder qb = new QueryBuilder(true);
            qb.Clear();
            qb.AddSelect(PL_JournalEntry.DocumentNo);
            qb.AddSelect(PL_JournalEntry.DocumentDate);
            qb.AddSelect(PL_JournalEntry.JournalNo);
            qb.AddSelect(PL_JournalEntry.PostingDate);
            qb.AddSelect(PL_JournalEntry.Type);
            qb.AddSelect(PL_JournalEntry.Code);
            qb.AddSelect(PL_JournalEntry.Description);
            qb.AddSelect(PL_JournalEntry.InvoiceType);

            qb.AddSelectAll(PL_JournalEntryTaxDetail.Name);
            qb.AddFrom(PL_JournalEntryTaxDetail.Name);
            qb.AddJoin(QueryBuilder.JoinType.INNER, PL_JournalEntry.JournalNo, PL_JournalEntryTaxDetail.JournalNo);
            SqlABParameter pFrom = new SqlABParameter("@p1", PL_JournalEntry.PostingDate);
            SqlABParameter pTo = new SqlABParameter("@p2", PL_JournalEntry.PostingDate);
            qb.AddBetween(PL_JournalEntry.PostingDate, pFrom, pTo);
            qb.AddCompare<TaxRegisterType>(PL_JournalEntry.TaxRegister, eTaxRegister.GetValue());
            if (eTaxRegister.GetValue() == TaxRegisterType.E_TaxSale)
                qb.AddOrder(PL_JournalEntry.DocumentNo);
            qb.AddOrder(PL_JournalEntry.DocumentDate);
            qb.AddOrder(PL_JournalEntry.JournalNo);



            pFrom.Value = GetStartDate();
            pTo.Value = GetEndDate(); ;

            using (SqlABCommand scc = new SqlABCommand(base.providerType, GlobalInfo.SqlConnection))
            {
                scc.CommandText = qb.Query;
                scc.Parameters.Add(pFrom);
                scc.Parameters.Add(pTo);
                SqlABDataReader dr = scc.ExecuteReader();
                while (dr.Read())
                    AddRow(dr);
                dr.Close();
            }

            totalAmount = 0;
            foreach (KeyValuePair<string, totals> tot in taxTotals)
            {
                DSTaxRegister.TaxSummaryRow tsr = dsTaxRegister.TaxSummary.NewTaxSummaryRow();
                drTaxCode.Find(tot.Key);
                tsr[PL_JournalEntryTaxDetail.TaxCode.Name] = drTaxCode.GetValue<string>(PL_TaxCode.Description);
                tsr[PL_JournalEntryTaxDetail.Amount.Name] = tot.Value.Amount;
                tsr[PL_JournalEntryTaxDetail.Tax.Name] = tot.Value.Tax;
                tsr[PL_JournalEntryTaxDetail.Total.Name] = tot.Value.Tax + tot.Value.Amount;

                totalAmount += tot.Value.Tax;
                dsTaxRegister.TaxSummary.Rows.Add(tsr);
            }
            return dsTaxRegister.JournalEntryTaxDetail.Rows.Count > 0;
        }

        private void AddRow(SqlABDataReader dr)
        {
            double amount, tax;
            string taxcode;
            DSTaxRegister.JournalEntryTaxDetailRow jer = dsTaxRegister.JournalEntryTaxDetail.NewJournalEntryTaxDetailRow();

            switch (dr.GetValue<InvoiceType>(PL_JournalEntry.InvoiceType))
            {
                case InvoiceType.E_CreditNoteEm:
                    jer["DocType"] = "NC";
                    break;
                case InvoiceType.E_InvoiceEm:
                    jer["DocType"] = "FT";
                    break;
                case InvoiceType.E_DebitNoteEm:
                    jer["DocType"] = "ND";
                    break;
            }

            jer[PL_JournalEntry.DocumentNo.Name] = dr.GetValue<string>(PL_JournalEntry.DocumentNo);
            jer[PL_JournalEntry.DocumentDate.Name] = dr.GetValue<DateTime>(PL_JournalEntry.DocumentDate);
            jer[PL_JournalEntry.JournalNo.Name] = dr.GetValue<string>(PL_JournalEntry.JournalNo);
            jer[PL_JournalEntry.PostingDate.Name] = dr.GetValue<DateTime>(PL_JournalEntry.PostingDate);
            drMasterType.Find(dr.GetValue<string>(PL_JournalEntry.Type));
            jer[PL_JournalEntry.Type.Name] = drMasterType.GetValue<string>(PL_MasterType.Description);
            jer[PL_JournalEntry.Code.Name] = dr.GetValue<string>(PL_JournalEntry.Code);
            jer[PL_JournalEntry.Description.Name] = dr.GetValue<string>(PL_JournalEntry.Description);

            if (dr.GetValue<InvoiceType>(PL_JournalEntry.InvoiceType) == InvoiceType.E_CreditNoteEm ||
                dr.GetValue<InvoiceType>(PL_JournalEntry.InvoiceType) == InvoiceType.E_DebitNoteRc)
            {
                jer[PL_JournalEntryTaxDetail.Amount.Name] = amount = -dr.GetValue<double>(PL_JournalEntryTaxDetail.Amount);
                jer[PL_JournalEntryTaxDetail.Tax.Name] = tax = -dr.GetValue<double>(PL_JournalEntryTaxDetail.Tax);
            }
            else
            {
                jer[PL_JournalEntryTaxDetail.Amount.Name] = amount = dr.GetValue<double>(PL_JournalEntryTaxDetail.Amount);
                jer[PL_JournalEntryTaxDetail.Tax.Name] = tax = dr.GetValue<double>(PL_JournalEntryTaxDetail.Tax);
            }
            jer[PL_JournalEntryTaxDetail.Total.Name] = amount + tax;
            taxcode = dr.GetValue<string>(PL_JournalEntryTaxDetail.TaxCode);

            drTaxCode.Find(taxcode);
            jer[PL_JournalEntryTaxDetail.TaxCode.Name] = drTaxCode.GetValue<string>(PL_TaxCode.Description);

            dsTaxRegister.JournalEntryTaxDetail.Rows.Add(jer);

            if (!taxTotals.ContainsKey(taxcode))
                taxTotals.Add(taxcode, new totals());

            taxTotals[taxcode].Amount += amount;
            taxTotals[taxcode].Tax += tax;
        }

        protected override EmailArgs SendEmail()
        {
            EmailArgs ea = new EmailArgs();
            ea.Subject = Title;
            ea.Attachment = ExportToPdf(Title);
            return ea;
        }

        private void cbbYear_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!cbbYear.Text.IsEmpty() && drLiquidationTax.Find(int.Parse(cbbYear.Text)))
                eMonthName.Refresh(true);
        }

        private DateTime GetStartDate()
        {
            if (eMonthName.GetValue() <= PeriodType.E_December)
                return new DateTime(int.Parse(cbbYear.Text), eMonthName.GetValue().Int(), 1);
            else
            {
                return new DateTime(int.Parse(cbbYear.Text), (eMonthName.GetValue().Int() - 13) * 3 + 1, 1);
            }
        }

        private DateTime GetEndDate()
        {
            if (eMonthName.GetValue() <= PeriodType.E_December)
                return new DateTime(int.Parse(cbbYear.Text), eMonthName.GetValue().Int(), DateTime.DaysInMonth(int.Parse(cbbYear.Text), eMonthName.GetValue().Int()));
            else
                return new DateTime(int.Parse(cbbYear.Text), (eMonthName.GetValue().Int() - 12) * 3, DateTime.DaysInMonth(int.Parse(cbbYear.Text), (eMonthName.GetValue().Int()-12) * 3));
        }

        private class totals
        {
            public double Amount { get; set; }
            public double Tax { get; set; }
        }
    }
}